import { customBaseQuery } from './config'
import { TCatalogData, TProductData, TProductReview } from '../store/types'
import { createApi } from '@reduxjs/toolkit/query/react'

export type TBEAllProductsResponse = {
	total: number
	products: TCatalogData[]
}

type TAllProductsResponse = {
	totalAllProducts: number
	allProducts: TCatalogData[]
}

type TSetLikeRequest = {
	_id: string
}

type TGetProductsRequest = {
	page: number
	limit: number
	search?: string
}

type TBEGetProductsResponse = {
	total: number
	products: TCatalogData[]
}

type TGetProductRequest = {
	id: string
}

export type TBEGetProductResponse = TProductData

type TAddProductReviewRequest = {
	productId: TProductData['_id']
	review: {
		rating: TProductReview['rating']
		text: TProductReview['text']
	}
}
type TBEAddProductReviewResponse = TProductData

type TDeleteProductReviewRequest = {
	productId: TProductData['_id']
	review: {
		_id: TProductReview['_id']
		rating: TProductReview['rating']
		text: TProductReview['text']
	}
}
type TBEDeleteProductReviewResponse = TProductData

export const productsApiSlice = createApi({
	reducerPath: 'productsApiSlice',
	baseQuery: customBaseQuery,
	tagTypes: ['AllProducts', 'Products', 'Product'],
	endpoints: (builder) => ({
		getAllProducts: builder.query<TAllProductsResponse, void>({
			query: () => ({
				url: '/products',
				method: 'GET',
			}),
			transformResponse: (response: TBEAllProductsResponse) => {
				return {
					totalAllProducts: response.total,
					allProducts: response.products,
				}
			},
			providesTags: ['AllProducts'],
		}),
		setLike: builder.mutation<TAllProductsResponse, TSetLikeRequest>({
			query: ({ _id }) => ({
				url: `/products/likes/${_id}`,
				method: 'PUT',
			}),
			invalidatesTags: ['AllProducts', 'Product'],
		}),
		setDislike: builder.mutation<TAllProductsResponse, TSetLikeRequest>({
			query: ({ _id }) => ({
				url: `/products/likes/${_id}`,
				method: 'DELETE',
			}),
			invalidatesTags: ['AllProducts', 'Product'],
		}),
		getProducts: builder.query<TBEGetProductsResponse, TGetProductsRequest>({
			query: ({ page, limit, search }) => ({
				url:
					`/products/?page=${page}&limit=${limit}` +
					`${search ? `&query=${search}` : ''}`,
				method: 'GET',
			}),
			// Переопределяем ключ кэширование на основе эндпоинта и поиска
			serializeQueryArgs: ({ endpointName, queryArgs: { search } }) => {
				return endpointName + search
			},
			// объединяем данные и кэша
			merge: (currentCache, newValue, { arg: { page } }) => {
				if (page === 1) return
				currentCache.products.push(...newValue.products)
				currentCache.total = newValue.total
			},
			forceRefetch({ currentArg, previousArg }) {
				return currentArg !== previousArg
			},
		}),
		getProduct: builder.query<TBEGetProductResponse, TGetProductRequest>({
			query: ({ id }) => ({
				url: `/products/${id}`,
				method: 'GET',
			}),

			providesTags: ['Product'],
		}),
		addProductReview: builder.mutation<
			TBEAddProductReviewResponse,
			TAddProductReviewRequest
		>({
			query: (params) => ({
				url: `/products/review/${params.productId}`,
				method: 'POST',
				body: params.review,
			}),
			invalidatesTags: ['Product'],
		}),
		deleteProductReview: builder.mutation<
			TBEDeleteProductReviewResponse,
			TDeleteProductReviewRequest
		>({
			query: (params) => ({
				url: `/products/review/${params.productId}/${params.review._id}`,
				method: 'DELETE',
				body: params.review,
			}),
			invalidatesTags: ['Product'],
		}),
	}),
})

export const {
	useGetAllProductsQuery,
	useSetLikeMutation,
	useSetDislikeMutation,
	useGetProductsQuery,
	useGetProductQuery,
	useAddProductReviewMutation,
	useDeleteProductReviewMutation,
} = productsApiSlice
